package com.yanqu.road.logic.rank;

import com.yanqu.road.logic.pb.RankPb;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.entity.activity.UnionActivityConditionData;
import com.yanqu.road.entity.rank.UnionActivityRank;
import com.yanqu.road.logic.sort.UnionActivityRankSort;
import com.yanqu.road.pb.rank.UnionActivityRankProto;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigInteger;
import java.util.*;

public class UnionActivityRankListModel {

    private static Logger logger = LogManager.getLogger(UnionActivityRankListModel.class.getName());

    private int rankNum = GameConfig.RANK_DEFAULT_MAX_COUNT;

    private UnionActivityRankSort sorter;

    private LinkedList<UnionActivityRank> rankList;

    private int activityId;

    private UnionActivityRankProto.UnionActivityRankListMsg.Builder rankListMsg;

    public void setRankNum(int rankNum) {
        this.rankNum = rankNum;
    }

    public int getRankNum() {
        return rankNum;
    }

    public int getActivityId() {
        return activityId;
    }

    public void setActivityId(int activityId) {
        this.activityId = activityId;
    }

    public UnionActivityRankListModel(int activityId) {
        this.activityId = activityId;
        sorter = new UnionActivityRankSort();
        rankList = new LinkedList<>();
        rankListMsg = UnionActivityRankProto.UnionActivityRankListMsg.newBuilder();
    }

    public LinkedList<UnionActivityRank> getRankList() {
        return rankList;
    }

    public UnionActivityRankProto.UnionActivityRankListMsg.Builder getRankListMsg() {
        return rankListMsg;
    }

    public void initRankList(Map<String, UnionActivityConditionData> conditionDataMap) {
        for(UnionActivityConditionData conditionData : conditionDataMap.values()){
            if(conditionData.getMemberUserCount() > 0) {
                UnionActivityRank rank = new UnionActivityRank();
                rank.setUnionUid(conditionData.getUnionUid());
                rank.setUnionBaseInfo(conditionData.getUnionBaseInfo());
                rank.setValue(conditionData.getValue());
                rank.setLastUpdateTime(conditionData.getLastUpdateTime());

                rankList.add(rank);
            }
        }
        rankList.sort(sorter);
        initRankListMsg();
    }

    private void initRankListMsg() {
        rankListMsg = RankPb.parseUnionActivityRankListMsg(rankNum, rankList);
    }


    public void initRankList() {
        initRankListMsg();
    }


    public void removeRank(String unionUid) {
        synchronized (this) {
            for (UnionActivityRank rank : rankList) {
                if (Objects.equals(rank.getUnionUid(), unionUid)) {
                    rank.setValue(BigInteger.ZERO);
                }
            }
            rankList.removeIf(m -> Objects.equals(m.getUnionUid(), unionUid));
            initRankListMsg();
        }
    }

    public int getMyRank(String unionUid) {
        int rank = -1;
        synchronized (this) {
            for(int i = 0; i < rankList.size(); i++){
                UnionActivityRank unionActivityRank = rankList.get(i);
                if(Objects.equals(unionActivityRank.getUnionUid(), unionUid)){
                    rank = i + 1;
                    break;
                }
            }
        }
        if(rank > rankNum){
            rank = -1;
        }
        return rank;
    }

    public BigInteger getMyUnionValue(String unionUid){
        synchronized (this) {
            for(UnionActivityRank unionActivityRank : rankList){
                if(Objects.equals(unionActivityRank.getUnionUid(), unionUid)){
                    return unionActivityRank.getValue();
                }
            }
        }
        return BigInteger.ZERO;
    }

    private UnionActivityRank getUnionRankInfo(String unionUid){
        synchronized (this) {
            for(UnionActivityRank unionActivityRank : rankList){
                if(Objects.equals(unionActivityRank.getUnionUid(), unionUid)){
                    return unionActivityRank;
                }
            }
        }
        return null;
    }


    /**
     * 更新排行
     */
    public UnionActivityRank rankChange(UnionActivityConditionData unionActivityConditionData) {
        if(null == unionActivityConditionData){
            return null;
        }
        boolean isChange = false;
        UnionActivityRank unionRank;
        synchronized (this) {
            unionRank = getUnionRankInfo(unionActivityConditionData.getUnionUid());
            if(null != unionRank){
                unionRank.setValue(unionActivityConditionData.getValue());
                unionRank.setUnionBaseInfo(unionActivityConditionData.getUnionBaseInfo());
                unionRank.setLastUpdateTime(unionActivityConditionData.getLastUpdateTime());
                isChange = true;
            }else {
                int size = rankList.size();
                if (size < rankNum) {
                    unionRank = initActivityRank(unionActivityConditionData);
                    rankList.addLast(unionRank);
                    isChange = true;
                } else if (rankList.getLast().getValue().compareTo(unionActivityConditionData.getValue()) <0) {
                    rankList.removeLast();
                    unionRank = initActivityRank(unionActivityConditionData);
                    rankList.addLast(unionRank);
                    isChange = true;
                }
            }
            if(isChange) {
                rankList.sort(sorter);
                initRankListMsg();
            }
        }
        return unionRank;
    }

    public UnionActivityRank initActivityRank(UnionActivityConditionData unionActivityConditionData) {
        UnionActivityRank rank = new UnionActivityRank();
        rank.setUnionUid(unionActivityConditionData.getUnionUid());
        rank.setUnionBaseInfo(unionActivityConditionData.getUnionBaseInfo());
        rank.setValue(unionActivityConditionData.getValue());
        rank.setLastUpdateTime(unionActivityConditionData.getLastUpdateTime());
        return rank;
    }
}
